home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************************************
- *
- *
- * ObjectMacZapp -- a standard Mac OOP application template
- *
- *
- *
- * ZWindow.cpp -- the window object
- *
- *
- *
- *
- *
- * © 1996, Graham Cox
- *
- * 14/11/96- modified to support undo and printing.
- *
- *
- *************************************************************************************************/
-
-
- #include "ZWindow.h"
- #include "MacZoop.h"
- #include "ZEventHandler.h"
- #include "ZUndoTask.h"
-
-
- #ifdef APPEARANCE_MGR_AWARE
- #include "Appearance.h"
- #endif
-
- static short CalculateOffsetAmount( short idealStartPoint,
- short idealEndPoint,
- short idealOnScreenStartPoint,
- short idealOnScreenEndPoint,
- short screenEdge1,
- short screenEdge2 );
-
-
- /*------------------------------*** CONSTRUCTOR ***---------------------------------*/
-
- ZWindow::ZWindow(ZCommander* aBoss, const short windowID)
- : ZCommander(aBoss)
- {
- windID = windowID;
- macWindow = NULL;
- dirty = FALSE;
- isNamed = FALSE;
- macFile.vRefNum = kNoFile;
- macFType = 0;
- printable = FALSE;
- isPrinting = FALSE;
- floating = FALSE;
- disableAutoClose = FALSE;
-
- // initial sizeRect is set to an arbitrary size
-
- SetRect(&sizeRect,120,90,2000,2000);
- }
-
- /*------------------------------*** DESTRUCTOR ***---------------------------------*/
-
- ZWindow::~ZWindow()
- {
- // if the application has an undo task pertaining to this window, delete it.
-
- ZUndoTask* curTask = gApplication->GetUndoTask();
-
- if (curTask && (curTask->GetUndoTarget() == this))
- gApplication->SetTask( NULL );
-
- // wMgr no longer needs us
-
- gWindowManager->RemoveWindow( this );
-
- if ( macWindow )
- DisposeWindow( macWindow );
- }
-
-
- /*--------------------------------*** INITZWINDOW ***---------------------------------*/
- /*
-
- initialise this object. By default, this just makes the window
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::InitZWindow()
- {
- MakeMacWindow( windID );
-
- // tell the window manager of our existence. This must be done after the
- // full build of the mac window since the window manager needs to get
- // information from it. Thus if you override this method, make sure you
- // make the same call.
-
- gWindowManager->AddWindow( this );
- }
-
-
- /*------------------------------*** MAKEMACWINDOW ***---------------------------------*/
- /*
-
- create the macintosh window that this object looks after
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::MakeMacWindow( const short windID )
- {
- if ( gMacInfo.supportsColour )
- FailNIL( macWindow = GetNewCWindow( windID, NULL, NULL ));
- else
- FailNIL( macWindow = GetNewWindow( windID, NULL, NULL ));
-
- // so we can identify the window, we set the windowKind to a special value. The refCon
- // contains the object reference so we can freely locate the object from the window and
- // vice versa. Your application must not touch the refCon- add members to your window
- // objects instead.
-
- ((WindowPeek) macWindow)->windowKind = IS_ZWINDOW_KIND;
- SetWRefCon( macWindow, (long) this );
-
- // what WDEF are we using for this window? If it's one of the known "floater" types,
- // then we should set the flaoting flag automatically- one less thing the programmer
- // needs to worry about, and will work for the common cases.
-
- WindTemplateHdl wTH = (WindTemplateHdl) GetResource( 'WIND', windID );
-
- if ( wTH )
- {
- // the system floater has a proc of 124. The commonly used "Infinity" windoid
- // has a proc of 128.
-
- short pID = (*wTH)->procID / 16;
-
- // with appearance manager, the WDEF IDs for floating windows are 66 & 67
-
- #ifdef APPEARANCE_MGR_AWARE
-
- if ( gMacInfo.hasAppearanceMgr )
- floating |= ( pID == kStdUtilityDefProcResID ||
- pID == kStdUtilitySideTitleDefProcResID );
-
- #endif
-
- floating |= ( pID == kFloatingWindowDefinition ||
- pID == kInfinityWindoidDefinition );
-
- ReleaseResource((Handle) wTH );
- }
-
- // allocate a unique title. This we'll base on the current title
- // (which should be "untitled"), with an appended digit to ensure uniqueness
-
- Str255 wTitle;
-
- GetWTitle( macWindow, wTitle );
- if ( gWindowManager->GetUniqueUntitledName( wTitle ))
- SetWTitle( macWindow, wTitle );
-
- CopyPString( wTitle, macFile.name );
-
- // if appearance savvy, make a root control for the window so stuff can be
- // embedded into it easily.
-
- #ifdef APPEARANCE_MGR_AWARE
-
- if ( gMacInfo.hasAppearanceMgr )
- {
- ControlHandle rc;
-
- FailOSErr( CreateRootControl( macWindow, &rc ));
- }
-
- #endif
- }
-
-
- /*----------------------------------*** ACTIVATE ***----------------------------------*/
- /*
-
- this window is becoming active
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::Activate()
- {
- // the window is activated. If appearance mgr savvy, activate root control:
-
- #ifdef APPEARANCE_MGR_AWARE
-
- if ( gMacInfo.hasAppearanceMgr )
- {
- OSErr theErr;
- ControlHandle rc;
-
- theErr = GetRootControl( macWindow, &rc );
-
- if ( theErr == noErr )
- FailOSErr( ActivateControl( rc ));
- }
- else
- DrawGrow();
-
- #else
-
- DrawGrow();
-
- #endif
- }
-
-
- /*---------------------------------*** DEACTIVATE ***---------------------------------*/
- /*
-
- this window is becoming inactive
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::Deactivate()
- {
- #ifdef APPEARANCE_MGR_AWARE
-
- if ( gMacInfo.hasAppearanceMgr )
- {
- OSErr theErr;
- ControlHandle rc;
-
- theErr = GetRootControl( macWindow, &rc );
-
- if ( theErr == noErr )
- FailOSErr( DeactivateControl( rc ));
- }
- else
- DrawGrow();
-
- #else
-
- DrawGrow();
-
- #endif
- }
-
-
- /*------------------------------------*** FOCUS ***-----------------------------------*/
- /*
-
- make this window the current port ready for drawing or clicking
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::Focus()
- {
- SetPort( macWindow );
- SetOrigin( 0, 0 );
- ClipRect( &macWindow->portRect );
- }
-
-
- /*--------------------------------*** POSTREFRESH ***---------------------------------*/
- /*
-
- invalidate the window contents so that it gets redrawn on the next update
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::PostRefresh()
- {
- Focus();
- InvalRect( &macWindow->portRect );
- }
-
- /*------------------------------------*** DRAW ***------------------------------------*/
- /*
-
- draw the contents of this window. This is the main draw dispatcher.
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::Draw()
- {
- // if we are growable, we should clip out the scrollbar areas otherwise
- // the DrawContent call may erase the growbox, etc
-
- short v = GetWVariant(macWindow);
-
- if (v == documentProc || v == zoomDocProc)
- {
- Rect r = macWindow->portRect;
-
- r.right -= kStdScrollbarWidth;
- r.bottom -= kStdScrollbarWidth;
- ClipRect( &r );
- }
- DrawContent();
-
- SetOrigin( 0, 0 );
- ClipRect( &macWindow->portRect );
- DrawControls( macWindow );
-
- DrawGrow();
- }
-
-
- /*-------------------------------*** DRAWCONTENT ***----------------------------------*/
- /*
-
- draw the content area of this window- this is what will draw the meaningful part
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::DrawContent()
- {
- if (! isPrinting)
- EraseRect( &macWindow->portRect );
- }
-
-
- /*---------------------------------*** CALCPAGES ***----------------------------------*/
- /*
-
- compute the pagination for printing. By default this divides the contect rect up to be
- tiled across the paper rect, horizontal major order. Override for other methods
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::CalcPages( const Rect& paperRect, short* pagesH, short* pagesV )
- {
- Rect cr;
- short pWidth, pHeight, cWidth, cHeight;
-
- GetBounds( &cr );
-
- pWidth = paperRect.right - paperRect.left;
- pHeight = paperRect.bottom - paperRect.top;
-
- cWidth = cr.right - cr.left;
- cHeight = cr.bottom - cr.top;
-
- *pagesH = (cWidth / pWidth) + 1;
- *pagesV = (cHeight / pHeight) + 1;
- }
-
- /*-------------------------------*** PRINTONEPAGE ***---------------------------------*/
- /*
- draw the requested page (numbered according to the pagination you set up) to the current
- port, which will be a printing port when called. By default this manipulates the origin
- and draws the content, suitably clipped, to the port. Override for other behaviour.
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::PrintOnePage( const short pageNum, const Rect& paperRect )
- {
- Rect pr;
- short hp, vp, dH, dV;
-
- // calculate the printing area
-
- CalcPages( paperRect, &hp, &vp );
- pr = paperRect;
-
- dH = paperRect.right * ((pageNum - 1) % hp);
- dV = paperRect.bottom * ((pageNum - 1) / hp);
-
- OffsetRect( &pr, dH, dV );
-
- // make sure that the text & pen attributes in the window and printing port match
- // in case the DrawContent routine doesn't set them as it goes.
-
- TextFont( macWindow->txFont );
- TextSize( macWindow->txSize );
- TextFace( macWindow->txFace );
- TextMode( srcOr );
- PenSize( macWindow->pnSize.h, macWindow->pnSize.v );
- PenPat( &macWindow->pnPat );
- PenMode( macWindow->pnMode );
-
- // draw the contents.
-
- SetOrigin( pr.left, pr.top );
- ClipRect( &pr );
-
- DrawContent();
- SetOrigin( 0, 0 );
- }
-
-
- /*------------------------------*** GETCONTENTRECT ***--------------------------------*/
- /*
-
- return the content area
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::GetContentRect( Rect* contents )
- {
- *contents = macWindow->portRect;
- }
-
-
-
- /*---------------------------------*** DRAWGROW ***-----------------------------------*/
- /*
-
- draw the grow icon if the window type indicates this is appropriate
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::DrawGrow()
- {
- short v = GetWVariant(macWindow);
-
- if ( v == documentProc || v == zoomDocProc )
- {
- Rect r = macWindow->portRect;
-
- r.left = r.right - kStdScrollbarWidth;
- r.top = r.bottom - kStdScrollbarWidth;
-
- ClipRect( &r );
- DrawGrowIcon( macWindow );
- }
- }
-
-
- /*-----------------------------------*** CLICK ***------------------------------------*/
- /*
-
- the user clicked in the content area of this window. By default this does nothing.
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::Click( const Point mouse, const short modifiers )
- {
- }
-
-
- /*-----------------------------*** CLICKINSAMEPLACE ***-------------------------------*/
- /*
-
- should this click be considered a double-click? You can override this and return TRUE if
- the two points are to be considered in the same place for the purposes of determining
- a double-click. The default method always returns TRUE. The points passed are in the
- window's LOCAL coordinates.
-
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZWindow::ClickInSamePlace( const Point click1, const Point click2 )
- {
- return TRUE;
- }
-
-
- /*-------------------------------*** SETSIZERECT ***----------------------------------*/
- /*
-
- set minimum and maximum sizes for this window
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::SetSizeRect( const Rect& szRect )
- {
- sizeRect = szRect;
-
- // make sure max is not less than min:
-
- sizeRect.right = MAX( sizeRect.right, sizeRect.left );
- sizeRect.bottom = MAX( sizeRect.bottom, sizeRect.top );
-
- // if the window does not conform to the size constraints, change it's size so
- // that it does.
-
- Rect pr;
-
- pr = macWindow->portRect;
- SetSize( pr.right - pr.left, pr.bottom - pr.top, FALSE );
- }
-
-
- /*-------------------------------*** GETSIZERECT ***----------------------------------*/
- /*
-
- get minimum and maximum sizes for this window
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::GetSizeRect( Rect* szRect )
- {
- *szRect = sizeRect;
- }
-
-
- /*----------------------------------*** CLOSE ***-------------------------------------*/
- /*
-
- we want to close this window. If it needs to be saved, do that. The user may cancel this.
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZWindow::Close( const short phase )
- {
- // the user wants to close the window. This checks the dirty flag and if dirty, asks the
- // user if they want to save changes, if so, this calls save.
-
- // first see if we have any subsidiary windows and ask them to close
-
- if (! CloseSubsidiaryWindows( phase ))
- return FALSE;
-
- // they were all closed successfully, now check this one
-
- short check = kCloseNoSave;
-
- if ( dirty )
- {
- Str31 nameStr;
- Str31 phaseStr;
-
- GetName( nameStr );
- GetIndString( phaseStr, kMiscStrListID, ( phase == kRunning )? 1 : 2);
- ParamText( nameStr, phaseStr, NULL, NULL );
-
- SetCursor( &qd.arrow );
- check = Alert( kConfirmSaveAlertID, NULL ); // do you wish to save?
-
- if ( check == kConfirmSave )
- if (! Save( FALSE )) // if so, save the file
- check = kCloseCancel;
- }
-
- if ( check != kCloseCancel )
- {
- Hide();
-
- if ( gCurHandler == GetHandler()) // make the current handler this
- gCurHandler = itsBoss; // one's boss- i.e. the application
-
- ForgetThis();
- return TRUE; // was closed
- }
- else
- return FALSE; // wasn't closed
- }
-
-
- /*---------------------------*** CLOSESUBSIDIARYWINDOWS ***---------------------------*/
- /*
- ask any windows supervised by this one to close
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZWindow::CloseSubsidiaryWindows( const short phase )
- {
- Boolean allClosed = TRUE;
-
- if ( itsUnderlings )
- {
- // there are some commanders supervised by this object. If they are
- // window objects, call their close method
-
- ZWindow* w;
- long i = itsUnderlings->CountItems();
-
- while( i )
- {
- // use RTTI to make sure the object is some sort of window
-
- w = dynamic_cast<ZWindow*>(itsUnderlings->GetObject( i-- ));
-
- if (w)
- {
- // yes it is, so ask it to close
-
- if (! w->Close( phase ))
- {
- // if it didn't close, then abandon the closure sequence
-
- allClosed = FALSE;
- break;
- }
- }
- }
- }
-
- return allClosed;
- }
-
-
-
- /*-----------------------------------*** HIDE ***-------------------------------------*/
- /*
-
- make this window invisible
-
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::Hide()
- {
- gWindowManager->HideWindow( this );
- }
-
-
- /*-----------------------------------*** SHOW ***-------------------------------------*/
- /*
-
- make this window visible
-
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::Show()
- {
- gWindowManager->ShowWindow( this );
- }
-
-
- /*---------------------------------*** SELECT ***-------------------------------------*/
- /*
-
- make this window the active window
-
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::Select()
- {
- gWindowManager->SelectWindow( this );
- }
-
-
- /*---------------------------------*** PLACEAT ***------------------------------------*/
- /*
-
- position the window on the screen at h, v.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::PlaceAt( const short hGlobal, const short vGlobal )
- {
- MoveWindow( macWindow, hGlobal, vGlobal, FALSE );
- }
-
-
- /*------------------------------*** HANDLECOMMAND ***---------------------------------*/
- /*
-
- handle commands for a window, like Save, Save As, Close, etc.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::HandleCommand( const long aCmd )
- {
- EventRecord ev;
-
- switch ( aCmd )
- {
- case kCmdClose:
- gApplication->GetCurrentEvent( &ev );
-
- if ( ev.modifiers & optionKey )
- gApplication->CloseAll( Floats() );
- else
- Close( kRunning );
- break;
- case kCmdSave:
- Save( FALSE );
- break;
- case kCmdSaveAs:
- Save( TRUE );
- break;
- case kCmdRevert:
- Revert();
- break;
- }
-
- // pass other commands up to this object's boss (the app, in this case)
-
- inherited::HandleCommand( aCmd );
- }
-
-
- /*------------------------------*** HANDLECOMMAND ***---------------------------------*/
-
- void ZWindow::HandleCommand( const short menuID, const short itemID )
- {
- inherited::HandleCommand( menuID, itemID );
- }
-
-
- /*--------------------------------*** UPDATEMENUS ***---------------------------------*/
- /*
-
- updet the menus for a window, like Save, Save As, Close, etc.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::UpdateMenus()
- {
- // this enables the Close, Save and SaveAs commands.
-
- EventRecord ev;
-
- gApplication->GetCurrentEvent( &ev );
-
- // show "Close All" if the option key is down, else "Close"
-
- if (ev.modifiers & optionKey )
- gMenuBar->SetCommandText( kCmdClose, kMiscStrListID, 8 );
- else
- gMenuBar->SetCommandText( kCmdClose, kMiscStrListID, 9 );
-
- gMenuBar->EnableCommand( kCmdClose );
-
- if ( dirty )
- {
- gMenuBar->EnableCommand( kCmdSave );
-
- if ( isNamed )
- gMenuBar->EnableCommand( kCmdRevert );
- }
- gMenuBar->EnableCommand( kCmdSaveAs );
-
- // call the boss to enable his menus
-
- inherited::UpdateMenus();
- }
-
-
- /*-----------------------------------*** SETTASK ***----------------------------------*/
- /*
- submit an undoable task for this window. This updates the global undo task and marks the
- document as dirty.
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::SetTask( ZUndoTask* aTask )
- {
- // if were not dirty when the task arrives, then this must be the first task. Let it
- // know so that if the task is undone, it can clear the dirty flag so that undoing the
- // first task doesn't result in the "save changes?" alert.
-
- if ( ! dirty )
- aTask->SetIsFirstTask();
-
- dirty = TRUE; // document has been changed by the task
-
- gApplication->SetTask( aTask );
- }
-
-
- /*---------------------------------*** SETSIZE ***------------------------------------*/
- /*
-
- set this window to the width and height passed
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::SetSize( const short width, const short height, const Boolean reDraw )
- {
- // sets the window's size to the width and height passed, constrained to sizeRect.
-
- short w, h;
-
- w = MIN( sizeRect.right, MAX( width, sizeRect.left ));
- h = MIN( sizeRect.bottom, MAX( height, sizeRect.top ));
-
- if (( w != macWindow->portRect.right - macWindow->portRect.left ) ||
- ( h != macWindow->portRect.bottom - macWindow->portRect.top ))
- {
- Focus();
- if ( reDraw )
- EraseRect( &macWindow->portRect );
-
- SizeWindow( macWindow, w, h, reDraw );
-
- if ( reDraw )
- Draw();
- }
- }
-
-
- /*-----------------------------------*** ZOOM ***-------------------------------------*/
- /*
-
- Zoom this window between the standard and user states. This implements intelligent zoom-
- ing as recommended by the Apple HIG people. It may appear complex and indeed it probably
- is, however, the results are worth it since the zooming of windows almost always does
- exactly the most correct thing for your data- automatically! It also deals with any number
- of multiple monitors. You can always override this if you want something different.
- Based largely on code by Dean Yu, Apple Computer Inc.
- ----------------------------------------------------------------------------------------*/
-
- #define kNudgeSlop 2
- #define kIconAllowance 64
-
-
- void ZWindow::Zoom( const short partCode )
- {
- RgnHandle contRgn, strucRgn, scratchRgn;
- Rect portRect, crBBox, srBBox, zwBounds, wpOnScreen;
- short wfTop, wfLeft, wfBottom, wfRight;
- long largestArea = 0;
- GDHandle aScreen, targetMonitor;
-
- Focus();
- EraseRect( &macWindow->portRect );
-
- // calculate the most intelligent zoom state for the window and set the
- // standard state to it. The most intelligent state is on the monitor with
- // the largest area of the window, and that involves the minimum amount of
- // window movement.
-
- if ( partCode == inZoomOut )
- {
- GetWindowContentRgn( macWindow, contRgn = NewRgn()); // copland macro
- GetWindowStructureRgn( macWindow, strucRgn = NewRgn()); // copland macro
- portRect = macWindow->portRect;
- crBBox = (*contRgn)->rgnBBox;
- srBBox = (*strucRgn)->rgnBBox;
-
- // calculate the window frame size
-
- wfTop = crBBox.top - srBBox.top;
- wfLeft = crBBox.left - srBBox.left;
- wfBottom = srBBox.bottom - crBBox.bottom;
- wfRight = srBBox.right - crBBox.right;
-
- // the ideal size for this window is the max sizeRect. For scrollable windows,
- // this is set according to the bounds, which will give us the expected results
- // we now need to find the monitor that has the largest portion of the window
- // intersecting it.
-
- scratchRgn = NewRgn();
- SectRgn( GetGrayRgn(), contRgn, scratchRgn );
- if (EmptyRgn( scratchRgn ))
- zwBounds = srBBox;
- else
- zwBounds = crBBox;
- DisposeRgn( scratchRgn );
-
- // re-use srBBox for the new standard state rect, initially set to the
- // max sizeRect on the basis that this is the ideal window size if we had
- // an infinitely large monitor.
-
- SetRect( &srBBox, 0, 0, sizeRect.right, sizeRect.bottom );
-
- // walk the device list to determine which monitor the window should be
- // zoomed to:
-
- aScreen = GetDeviceList();
-
- while (aScreen)
- {
- long wpArea;
- // find the intersection of the window and the screen
-
- SectRect( &zwBounds, &(*aScreen)->gdRect, &wpOnScreen );
-
- // find the area of this portion
-
- OffsetRect( &wpOnScreen, -wpOnScreen.left, -wpOnScreen.top );
- wpArea = (long) wpOnScreen.right * (long) wpOnScreen.bottom;
-
- // if this is larger than the area found so far, keep track of
- // the monitor that contains it
-
- if (wpArea > largestArea)
- {
- largestArea = wpArea;
- targetMonitor = aScreen;
- }
- // look at the next monitor in the list
-
- aScreen = GetNextDevice( aScreen );
- }
-
- // ok, we have found the monitor we wish to zoom to. Store the monitor's
- // global rect in the wpOnScreen variable
-
- wpOnScreen = (*targetMonitor)->gdRect;
-
- // allow for the menubar and desktop icons if it's the main one
-
- if (targetMonitor == GetMainDevice())
- {
- wpOnScreen.top += GetMBarHeight();
- wpOnScreen.right -= kIconAllowance;
- }
-
- // OK, we can now calculate the standard rect we wish to zoom to (finally).
- // We calculate this using srBBox, since that now holds the new std state
-
- OffsetRect( &srBBox, crBBox.left, crBBox.top );
- srBBox.top -= wfTop;
- srBBox.left -= wfLeft;
- srBBox.right += wfRight;
- srBBox.bottom += wfBottom;
-
- // this is the ideal size for the window content. See if it needs nudging onto the
- // monitor
-
- SectRect( &srBBox, &wpOnScreen, &zwBounds );
- if (! EqualRect( &srBBox, &zwBounds ))
- {
- // needs to be nudged onto the monitor.
-
- short oH, oV;
-
- oH = CalculateOffsetAmount( srBBox.left, srBBox.right,
- zwBounds.left, zwBounds.right,
- wpOnScreen.left, wpOnScreen.right );
- oV = CalculateOffsetAmount( srBBox.top, srBBox.bottom,
- zwBounds.top, zwBounds.bottom,
- wpOnScreen.top, wpOnScreen.bottom );
- OffsetRect( &srBBox, oH, oV );
- }
-
- // If this still falls off the screen in any direction, it means that it is too large
- // for the montior, so it will need to be shrunk down to fit.
-
- SectRect( &srBBox, &wpOnScreen, &zwBounds);
- if (! EqualRect( &srBBox, &zwBounds ))
- {
- // nope- still doesn't fit. So shrink it down.
-
- if ((srBBox.right - srBBox.left) > (wpOnScreen.right - wpOnScreen.left))
- {
- srBBox.left = wpOnScreen.left + kNudgeSlop;
- srBBox.right = wpOnScreen.right - kNudgeSlop;
- }
-
- if ((srBBox.bottom - srBBox.top) > (wpOnScreen.bottom - wpOnScreen.top))
- {
- srBBox.top = wpOnScreen.top + kNudgeSlop;
- srBBox.bottom = wpOnScreen.bottom - kNudgeSlop;
- }
- }
-
- // adjust for the thickness of the frame and set the standard rect
-
- srBBox.top += wfTop;
- srBBox.left += wfLeft;
- srBBox.right -= wfRight;
- srBBox.bottom -= wfBottom;
-
- SetStdZoomRect( srBBox );
-
- DisposeRgn( contRgn );
- DisposeRgn( strucRgn );
- }
-
- // and.... Zoom!
-
- ZoomWindow( macWindow, partCode, FALSE );
- }
-
-
- /*------------------------------*** SETSTDZOOMRECT ***--------------------------------*/
- /*
- set the std rect for zoomable windows. The window zooms to this rect when the zoom box
- is clicked. If the window is not zoomable, this does nothing. The rect is in global coords.
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::SetStdZoomRect( const Rect& aRect )
- {
- short v = GetWVariant(macWindow);
-
- if (v == zoomDocProc ||
- v == zoomNoGrow)
- SetWindowStandardState( macWindow, &aRect ); // using copland macro
- }
-
-
- /*-----------------------------------*** SAVE ***-------------------------------------*/
- /*
-
- save the contents of the window to a file. This may display the standard file dialog.
- ----------------------------------------------------------------------------------------*/
-
-
- Boolean ZWindow::Save( const Boolean forceSaveAs )
- {
- // handles the save and save as commands.
-
- if (! isNamed || forceSaveAs)
- {
- // do Save As
-
- StandardFileReply macReply;
-
- PickFile( &macReply );
-
- if (macReply.sfGood)
- macFile = macReply.sfFile;
- else
- return FALSE; // user cancelled the save
- }
-
- // now do a save with the info.
-
- SetWatchCursor();
- SaveFile();
-
- return TRUE;
- }
-
-
- /*---------------------------------*** PICKFILE ***-----------------------------------*/
- /*
-
- display standard file dialog for picking a file for saving. Override if you want custom
- dialog, etc.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::PickFile( StandardFileReply* macReply )
- {
- Str31 prompt;
- Str255 name;
-
- GetIndString( prompt, kMiscStrListID, 3 );
- GetName( name );
-
- // make sure that filename is no longer than 31 chars
-
- name[0] = MIN( name[0], 31 );
-
- gWindowManager->Deactivate();
- StandardPutFile( prompt, name, macReply );
- gWindowManager->Activate();
- }
-
-
- /*---------------------------------*** SAVEFILE ***-----------------------------------*/
- /*
-
- write out the contents of the window to a file. This may rename the window. Note that you
- need to override this to actually write to a file (using a ZFile, perhaps), then call the
- inherited method to set the name and the state flags.
-
- ----------------------------------------------------------------------------------------*/
-
-
- void ZWindow::SaveFile()
- {
- // actually save the window's contents to the file.
-
- if (macFile.vRefNum != kNoFile)
- {
- SetTitle( macFile.name );
-
- // no longer dirty
-
- isNamed = TRUE;
- dirty = FALSE;
- }
- }
-
-
- /*---------------------------------*** GETNAME ***------------------------------------*/
- /*
-
- return the name of the window
-
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::GetName( Str255 name )
- {
- GetWTitle( macWindow, name );
- }
-
-
-
- /*----------------------------------*** REVERT ***------------------------------------*/
- /*
-
- revert the contents of the window to the original file
-
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::Revert()
- {
- // revert the contents. By default, this just calls open.
-
- Str31 title;
-
- GetName( title );
- ParamText( title, NULL, NULL, NULL );
-
- if ( Alert( kRevertConfirmAlertID, NULL ) == ok )
- {
- SetWatchCursor();
- OpenFile( macFType );
- }
- }
-
-
- /*---------------------------------*** SETFILE ***------------------------------------*/
- /*
-
- set the filespec for this window to the file passed.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::SetFile( const FSSpec& aFile )
- {
- macFile = aFile;
- }
-
-
- /*---------------------------------*** OPENFILE ***-----------------------------------*/
- /*
-
- open the file into the window's contents. This will set the name of the window to equal
- the filename
-
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::OpenFile( const OSType aFileType )
- {
- // this opens the current file into this window. This function should read the
- // contents of the file, replacing the current contents. The default method
- // does nothing. You should check that the vRefNum of the file spec is no kNoFile.
-
- if (macFile.vRefNum != kNoFile)
- {
- macFType = aFileType;
-
- SetTitle(macFile.name);
- isNamed = TRUE;
-
- if (IsVisible())
- PostRefresh();
-
- // delete any existing undo task for this window after opening a file,
- // since it probably contains stale data.
-
- ZUndoTask* task = gApplication->GetUndoTask();
-
- if (task && (task->GetUndoTarget() == this))
- gApplication->SetTask( NULL );
-
- dirty = FALSE;
- }
- }
-
-
- /*---------------------------------*** SETTITLE ***-----------------------------------*/
- /*
-
- set the title of the window
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::SetTitle( Str255 aTitle )
- {
- SetWTitle( macWindow, aTitle );
- }
-
-
-
- /*--------------------------------*** GETHANDLER ***----------------------------------*/
- /*
-
- return the object that begins the chain of command for this window. By default, it is the
- window itself.
-
- ----------------------------------------------------------------------------------------*/
-
- ZCommander* ZWindow::GetHandler()
- {
- return this;
- }
-
-
- /*-------------------------------*** ADJUSTCURSOR ***---------------------------------*/
- /*
- The cursor is over this window. Set its shape according to where it is and what modifiers
- are down. By default this just sets the cursor to an arrow. <mouse> is in local coords.
-
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::AdjustCursor( const Point mouse, const short modifiers )
- {
- SetCursor( &qd.arrow );
- }
-
-
- /*---------------------------------*** ISVISIBLE ***----------------------------------*/
- /*
- Is the window visible on screen?
- ----------------------------------------------------------------------------------------*/
-
- Boolean ZWindow::IsVisible()
- {
- return ((WindowPeek) macWindow)->visible;
- }
-
-
- /*-----------------------------*** GETTITLEBARHEIGHT ***------------------------------*/
- /*
- return the actual height of the window's title bar. This measures it from the regions
- and is thus totally WDEF safe.
- ----------------------------------------------------------------------------------------*/
-
- short ZWindow::GetTitleBarHeight()
- {
- RgnHandle sRgn, cRgn;
- short tHeight;
-
- FailNIL( sRgn = NewRgn());
- FailNIL( cRgn = NewRgn());
-
- GetStructureRegion( sRgn );
- GetContentRegion( cRgn );
-
- tHeight = (*cRgn)->rgnBBox.top - (*sRgn)->rgnBBox.top;
-
- DisposeRgn( sRgn );
- DisposeRgn( cRgn );
-
- return tHeight;
- }
-
-
- /*----------------------------*** GETSTRUCTUREREGION ***------------------------------*/
- /*
- copies the window's structure region into the passed region
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::GetStructureRegion( RgnHandle aRgn )
- {
- FailNILParam( aRgn );
-
- WindowPeek w = ( WindowPeek ) macWindow;
-
- Boolean wasFudged = FALSE;
- short h, v;
-
- // if the window isn't visible, the structure region isn't valid, so we have to
- // make it visible offscreen in order to get the region
-
- if ( ! w->visible )
- {
-
- GetGlobalPosition( &h, &v );
-
- MoveWindow( macWindow, h + 10000, v + 100, FALSE );
- ShowWindow( macWindow );
-
- wasFudged = TRUE;
- }
-
- CopyRgn( w->strucRgn, aRgn );
-
- if ( wasFudged )
- {
- HideWindow( macWindow );
- MoveWindow( macWindow, h, v, FALSE );
- }
- }
-
-
- /*-----------------------------*** GETCONTENTREGION ***-------------------------------*/
- /*
- copies the window's content region into the passed region
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::GetContentRegion( RgnHandle aRgn )
- {
- FailNILParam( aRgn );
-
- WindowPeek w = ( WindowPeek ) macWindow;
-
- Boolean wasFudged = FALSE;
- short h, v;
-
- // if the window isn't visible, the content region isn't valid, so we have to
- // make it visible offscreen in order to get the region
-
- if ( ! w->visible )
- {
-
- GetGlobalPosition( &h, &v );
-
- MoveWindow( macWindow, h + 10000, v + 100, FALSE );
- ShowWindow( macWindow );
-
- wasFudged = TRUE;
- }
-
- CopyRgn( w->contRgn, aRgn );
-
- if ( wasFudged )
- {
- HideWindow( macWindow );
- MoveWindow( macWindow, h, v, FALSE );
- }
- }
-
-
- /*-------------------------*** GETSTRUCTUREFRAMEBORDER ***----------------------------*/
- /*
- returns in <aRect> the thicknesses of the window borders. <top> is the title bar height,
- <left> and <right> are the thicknesses of the edges, and <bottom> is the thickness of the
- bottom.
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::GetStructureFrameBorder( Rect* aRect )
- {
- RgnHandle sRgn, cRgn;
- Rect s, c;
-
- FailNILParam( aRect );
-
- FailNIL( sRgn = NewRgn());
- FailNIL( cRgn = NewRgn());
-
- GetStructureRegion( sRgn );
- GetContentRegion( cRgn );
-
- s = (*sRgn)->rgnBBox;
- c = (*cRgn)->rgnBBox;
-
- aRect->top = c.top - s.top;
- aRect->left = c.left - s.left;
- aRect->right = s.right - c.right;
- aRect->bottom = s.bottom - c.bottom;
-
- DisposeRgn( sRgn );
- DisposeRgn( cRgn );
- }
-
-
- /*-----------------------------*** GETGLOBALPOSITION ***------------------------------*/
- /*
- returns the global position of the window on screen
- ----------------------------------------------------------------------------------------*/
-
- void ZWindow::GetGlobalPosition( short* hGlobal, short* vGlobal )
- {
- GrafPtr savePort;
- Point gloc;
-
- GetPort( &savePort );
- SetPort( macWindow );
-
- gloc = topLeft( macWindow->portRect );
- LocalToGlobal( &gloc );
-
- SetPort( savePort );
-
- *hGlobal = gloc.h;
- *vGlobal = gloc.v;
- }
-
-
- #pragma mark -
- /*---------------------------------******************----------------------------------*/
-
- static short CalculateOffsetAmount(short idealStartPoint, short idealEndPoint, short idealOnScreenStartPoint,
- short idealOnScreenEndPoint, short screenEdge1, short screenEdge2)
- {
- short offsetAmount;
-
- // First check to see if the window fits on the screen in this dimension.
- if ((idealStartPoint < screenEdge1) && (idealEndPoint > screenEdge2))
- offsetAmount = 0;
- else
- {
-
- // Find out how much of the window lies off this screen by subtracting the amount of the window
- // that is on the screen from the size of the entire window in this dimension. If the window
- // is completely offscreen, the offset amount is going to be the distance from the ideal
- // starting point to the first edge of the screen.
- if ((idealOnScreenStartPoint - idealOnScreenEndPoint) == 0)
- {
- // See if the window is lying to the left or above the screen
- if (idealEndPoint < screenEdge1)
- offsetAmount = screenEdge1 - idealStartPoint + kNudgeSlop;
- else
- // Otherwise, it’s below or to the right of the screen
- offsetAmount = screenEdge2 - idealEndPoint - kNudgeSlop;
- }
- else
- {
- // Window is already partially or completely on the screen
- offsetAmount = (idealEndPoint - idealStartPoint) -
- (idealOnScreenEndPoint - idealOnScreenStartPoint);
-
- // If we are offscreen a little, move the window in a few more pixels from the edge of the screen.
- if (offsetAmount != 0)
- offsetAmount += kNudgeSlop;
-
- // Check to see which side of the screen the window was falling off of, so that it can be
- // nudged in the opposite direction.
- if (idealEndPoint > screenEdge2)
- offsetAmount = -offsetAmount;
- }
- }
-
- return offsetAmount;
- }
-
-